package com.tzstcl.gen.service.impl;

import com.tzstcl.commons.utils.StringUtils;
import com.tzstcl.base.model.AjaxResult;
import com.tzstcl.gen.mapper.GenMapper;
import com.tzstcl.gen.model.GenTable;
import com.tzstcl.gen.model.GenTableColumn;
import com.tzstcl.gen.service.GenerateService;
import com.tzstcl.gen.util.Folder;
import com.tzstcl.gen.util.GenUtils;
import com.tzstcl.gen.util.Hump;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 公司：天筑科技股份有限公司
 * 作者：zgq
 * 日期：2018年12月22日
 * 说明：
 */
@Service
public class GenerateServiceImpl implements GenerateService {

    @Autowired
    GenMapper genMapper;

    /**
     * 生成代码
     *
     * @return
     */
    @Override
    public AjaxResult genCode(GenTable genTable) {
//        genTable.setAuthor("zhugq");
        genTable.setCurrentDate(new Date());
        genTable.setClassName(Hump.toCapitalizeCamelCase(genTable.getTableName()));
        genTable.setUnClassName(Hump.toCamelCase(genTable.getTableName()));
        String basePackage = "com.tzstcl";
        genTable.setPackageName(basePackage + "." + genTable.getModuleName() + "." + genTable.getSubModuleName());
        genTable.setFunctionNameSimple(genTable.getFunctionName());
        genTable.setPermissionPrefix(genTable.getModuleName() + (StringUtils.isNotBlank(genTable.getSubModuleName()) ? ":" + StringUtils.lowerCase(genTable.getSubModuleName()) : "") + ":" + genTable.getUnClassName());
        genTable.setColumns(getAllColumn(genTable.getTableName()));
        if (null != genTable.getColumns() && genTable.getColumns().size() > 0) {
            GenUtils.initColumnField(genTable);
            if ("status:0".equals(create(genTable))) {
                return AjaxResult.success();
            } else {
                return AjaxResult.error();
            }
        } else {
            return AjaxResult.error();
        }
    }

    /**
     * 获取某一个表的所有列
     *
     * @param tableName 数据表名称
     * @return
     */
    private List<GenTableColumn> getAllColumn(String tableName) {

        return genMapper.getAllColumn(tableName);
    }

    /**
     * 自动生成代码类
     *
     * @param genTable
     * @return
     */
    public String create(GenTable genTable) {

        Folder folder = new Folder();
        String packageName = genTable.getPackageName();
        String className = genTable.getClassName();
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
        try {
            cfg.setClassForTemplateLoading(GenTableColumn.class, "/templates/gen/curd");//模版路径
            Template templateEntity = cfg.getTemplate("/entity.ftl");//entity层
            Template templateMapper = cfg.getTemplate("/mapper.ftl");//dao层
            Template templateService = cfg.getTemplate("/service.ftl");//service层
            Template templateServiceImpl = cfg.getTemplate("/serviceImpl.ftl");//service层
            Template templateCtrl = cfg.getTemplate("/ctrl.ftl");//web层
            Template templateXml = cfg.getTemplate("/xml.ftl");//xml层
            Template templateViewList = cfg.getTemplate("/viewList.ftl");//页面
            Template templateViewForm = cfg.getTemplate("/viewForm.ftl");//页面
            Template templateViewDetail = cfg.getTemplate("/viewDetail.ftl");//页面
            Template templateViewEdit = cfg.getTemplate("/viewEdit.ftl");//页面
            StringWriter entity = new StringWriter();
            StringWriter dao = new StringWriter();
            StringWriter service = new StringWriter();
            StringWriter serviceImpl = new StringWriter();
            StringWriter ctrl = new StringWriter();
            StringWriter xml = new StringWriter();
            StringWriter viewList = new StringWriter();
            StringWriter viewForm = new StringWriter();
            StringWriter viewDetail = new StringWriter();
            StringWriter viewEdit = new StringWriter();
            templateEntity.process(genTable, entity);
            templateMapper.process(genTable, dao);
            templateService.process(genTable, service);
            templateServiceImpl.process(genTable, serviceImpl);
            templateCtrl.process(genTable, ctrl);
            templateXml.process(genTable, xml);
            templateViewList.process(genTable, viewList);
            templateViewForm.process(genTable, viewForm);
            templateViewDetail.process(genTable, viewDetail);
            templateViewEdit.process(genTable, viewEdit);
            String entityName = folder.folder(packageName + ".model", "1");//生成文件夹实体层
            String mapperName = folder.folder(packageName + ".mapper", "1");//生成文件夹dao层
            String serviceName = folder.folder(packageName + ".service", "1");//生成文件夹service层
            String serviceImplName = folder.folder(packageName + ".service.impl", "1");//生成文件夹serviceImpl层
            String ctrlName = folder.folder(packageName + ".ctrl", "1");//生成文件夹controller层
            String xmlName = folder.folder(packageName + ".mapper", "2");//生成文件夹mapping xml文件层

            String viewListName = folder.folder(genTable.getModuleName() + "." + genTable.getSubModuleName(), "3");//生成文件夹页面层
            //对应生成文件
            String entitys = className + ".java";
            String daos = className + "Mapper.java";
            String services = className + "Service.java";
            String serviceImpls = className + "ServiceImpl.java";
            String ctrls = className + "Ctrl.java";
            String xmls = className + "Mapper.xml";
            String viewListstr = genTable.getUnClassName() + "List.html";
            String viewFormstr = genTable.getUnClassName() + "Form.html";
            String viewDetailstr = genTable.getUnClassName() + "Detail.html";
            String viewEditstr = genTable.getUnClassName() + "Edit.html";
            try {
                FileWriter fwEntity = new FileWriter(entityName + "\\" + entitys, false);  // FileWriter 就是牛，如果文件名 的文件不存在，先创建再读写;存在的话直接追加写,关键字true表示追加
                fwEntity.write(String.valueOf(entity));
                fwEntity.close(); // 关闭写文件,每次仅仅写一行数据，因为一个读文件中仅仅一个唯一的od
                FileWriter fwMapper = new FileWriter(mapperName + "\\" + daos, false);
                fwMapper.write(String.valueOf(dao));
                fwMapper.close();
                FileWriter fwService = new FileWriter(serviceName + "\\" + services, false);
                fwService.write(String.valueOf(service));
                fwService.close();
                FileWriter fwServiceImpl = new FileWriter(serviceImplName + "\\" + serviceImpls, false);
                fwServiceImpl.write(String.valueOf(serviceImpl));
                fwServiceImpl.close();
                FileWriter fwCtrl = new FileWriter(ctrlName + "\\" + ctrls, false);
                fwCtrl.write(String.valueOf(ctrl));
                fwCtrl.close();
                FileWriter fwXml = new FileWriter(xmlName + "\\" + xmls, false);
                fwXml.write(String.valueOf(xml));
                fwXml.close();
                FileWriter fwViewList = new FileWriter(viewListName + "\\" + viewListstr, false);
                fwViewList.write(String.valueOf(viewList));
                fwViewList.close();
                FileWriter fwViewForm = new FileWriter(viewListName + "\\" + viewFormstr, false);
                fwViewForm.write(String.valueOf(viewForm));
                fwViewForm.close();
                FileWriter fwViewDetail = new FileWriter(viewListName + "\\" + viewDetailstr, false);
                fwViewDetail.write(String.valueOf(viewDetail));
                fwViewDetail.close();
                FileWriter fwViewEdit = new FileWriter(viewListName + "\\" + viewEditstr, false);
                fwViewEdit.write(String.valueOf(viewEdit));
                fwViewEdit.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "status:" + "0";
        } catch (IOException e) {
            e.printStackTrace();
            return "status:" + "1";
        } catch (TemplateException e) {
            e.printStackTrace();
            return "status:" + "1";
        }
    }

    /**
     * 获取所有的数据表
     *
     * @return
     */
    @Override
    public List<Map<String, String>> getAllTable() {
        return genMapper.getAllTable();
    }
}
